package com.msb.crm.service;

import com.msb.crm.base.BaseService;
import com.msb.crm.dao.RoleMapper;
import com.msb.crm.dao.UserMapper;
import com.msb.crm.dao.UserRoleMapper;
import com.msb.crm.model.UserModel;
import com.msb.crm.utils.AssertUtil;
import com.msb.crm.utils.Md5Util;
import com.msb.crm.utils.PhoneUtil;
import com.msb.crm.utils.UserIDBase64;
import com.msb.crm.vo.User;
import com.msb.crm.vo.UserRole;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;


@Service
public class UserService extends BaseService<User,Integer> {

    @Resource
    private UserMapper userMapper;

    @Autowired
    private UserRoleMapper userRoleMapper;


    /**
     * 用户登录
     * @param userName
     * @param userPwd
     */
    public UserModel userLogin(String userName, String userPwd)
    {
        //1.参数判断，判断用户姓名、用户密码非空
        checkLoginParams(userName,userPwd);

        //2.调用数据访问层，通过用户名查询用户记录，返回用户对象
        User user = userMapper.queryUserByName(userName);
        //3.判断用户对象是否为空
        AssertUtil.isTrue(user == null,"用户姓名不存在！");

        //4.判断密码是否正确，比较客户端传递的用户密码与数据库中查询的用户对象中的用户密码
        checkUserPwd(userPwd,user.getUserPwd());

        //5.返回构建用户对象
        return buildUserInfo(user);
    }

    /**
     * 构建需要返回给客户端的对象
     * @param user
     * @return
     */
    private UserModel buildUserInfo(User user) {
        UserModel userModel = new UserModel();

        userModel.setUserIdStr(UserIDBase64.encoderUserID(user.getId()));
        userModel.setUserName(user.getUserName());
        userModel.setTrueName(user.getTrueName());

        return userModel;
    }

    /**
     * 比较加密后的密码
     * @param userPwd
     * @param userPwd1
     */
    private void checkUserPwd(String userPwd, String userPwd1) {

        //将客户端传递的密码加密
        userPwd = Md5Util.encode(userPwd);
        //判断密码是否相等
        AssertUtil.isTrue(!userPwd.equals(userPwd1),"用户密码不正确！");

    }


    /**
     * 参数判断
     * @param userName
     * @param userPwd
     */
    private void checkLoginParams(String userName, String userPwd) {
        //验证用户姓名
        AssertUtil.isTrue(StringUtils.isBlank(userName),"用户姓名不能为空！");
        //验证用户密码
        AssertUtil.isTrue(StringUtils.isBlank(userPwd),"用户密码不能为空！");

    }


    /**
     * 修改密码
     * @param userId
     * @param oldPassword
     * @param newPassword
     * @param repeatPassword
     */

    //添加事务控制
    @Transactional
    public void updatePassword(Integer userId, String oldPassword, String newPassword, String repeatPassword) {
        //通过用户Id查询记录，返回用户对象
        User user = userMapper.selectByPrimaryKey(userId);
        //判断用户记录是否存在
        AssertUtil.isTrue( null == user,"待更新记录不存在！");

        //参数校验
        checkPasswordParams(user,oldPassword,newPassword,repeatPassword);

        //校验通过，设置新密码
        user.setUserPwd(Md5Util.encode(newPassword));

        //执行更新，返回受影响的行数
        AssertUtil.isTrue(userMapper.updateByPrimaryKeySelective(user)<1,"修改密码失败！");

    }


    /**
     * 修改密码的参数校验
     * @param user
     * @param oldPassword
     * @param newPassword
     * @param repeatPassword
     */
    public void checkPasswordParams(User user, String oldPassword, String newPassword, String repeatPassword) {
        //判断原始密码是否为空
        AssertUtil.isTrue(StringUtils.isBlank(oldPassword),"原始密码不能为空！");
        //判断原始密码是否正确
        AssertUtil.isTrue(!user.getUserPwd().equals(Md5Util.encode(oldPassword)),"原始密码不正确！");

        //判断新密码是否为空
        AssertUtil.isTrue(StringUtils.isBlank(newPassword),"新密码不能为空！");
        //判断新密码是否与原始密码一致
        AssertUtil.isTrue(oldPassword.equals(newPassword),"新密码不能与原始密码一致！");

        //判断确认密码是否为空
        AssertUtil.isTrue(StringUtils.isBlank(repeatPassword),"确认密码不能为空！");
        //判断确认密码是否与新密码一致
        AssertUtil.isTrue(!newPassword.equals(repeatPassword),"确认密码与新密码不一致！");

    }

//    查询所有的销售人员
    public List<Map<String,Object>> queryAllSales(){
        return userMapper.queryAllSales();
    }

    /**
     * 添加用户
     * @param user
     */
    @Transactional
    public void saveUser(User user){
        //1.参数校验
        checkUserParams(user.getUserName(),user.getEmail(),user.getPhone(),null);
        //2.设置其他默认参数
        user.setIsValid(1);
        user.setCreateDate(new Date());
        user.setUpdateDate(new Date());
        //使用MD5加密设置默认密码
        user.setUserPwd(Md5Util.encode("123456"));

        //3.执行添加，判断结果
        AssertUtil.isTrue(userMapper.insertSelective(user) < 1 ,"用户添加失败");
        relationUserRole(user.getId(),user.getRoleIds());
    }

    /**
     * 更新用户
     * @param user
     */
    @Transactional
    public void updateUser(User user){
        /*1.参数校验*/
        //1.通过id查询用户对象
        User temp = userMapper.selectByPrimaryKey(user.getId());
        //判断用户对象是否存在
        AssertUtil.isTrue(null == temp,"待更新记录不存在!");
        //验证参数
        checkUserParams(user.getUserName(), user.getEmail(), user.getPhone(),user.getId());
       /* 2.设置更新时间*/
        temp.setUpdateDate(new Date());
        /*3.执行更新*/
        AssertUtil.isTrue(userMapper.updateByPrimaryKeySelective(user)<1,"用户信息更新失败！");
        relationUserRole(user.getId(), user.getRoleIds());
    }


    public void deleteUser(Integer userId){
        User user = selectByPrimaryKey(userId);
        AssertUtil.isTrue(null == userId || null == user,"待删除记录不存在!");
        //判断用户是否绑定了角色信息
        int count = userRoleMapper.countUserRoleByUserId(userId);
        //如果绑定了角色信息则删除对应的信息
        if (count>0){
            AssertUtil.isTrue(userRoleMapper.deleteUserRoleByUserId(userId)!=count,"用户角色删除失败!");
        }
        user.setIsValid(0);
        AssertUtil.isTrue(updateByPrimaryKeySelective(user)<1,"用户记录删除失败!");
    }


    /**
     * 用户的参数校验
     * @param userName
     * @param email
     * @param phone
     */
    private void checkUserParams(String userName, String email, String phone,Integer userId) {
        //1.用户名不能为空
        AssertUtil.isTrue(StringUtils.isBlank(userName),"用户名不能为空！");

        //2.验证用户名是否存在
        User user = userMapper.queryUserByName(userName);
        //用户已存在
        // 如果是添加操作，数据库是没有数据的，数据库中只要查询到⽤户记录就表示不可⽤
        // 如果是修改操作，数据库是有数据的，查询到⽤户记录就是当前要修改的记录本身就表示可⽤，否则不可⽤
        // 数据存在，且不是当前要修改的⽤户记录，则表示其他⽤户占⽤了该⽤户名
        AssertUtil.isTrue(null != user && !(user.getId().equals(userId)),"该用户已存在!");
        //邮箱非空
        AssertUtil.isTrue(StringUtils.isBlank(email),"邮箱不能为空!");
        //电话号非空
        AssertUtil.isTrue(!PhoneUtil.isMobile(phone),"手机号码格式不正确!");
    }


    /**
     * 用户删除  批量
     * @param ids
     */
    public void deleteUserByIds(Integer[] ids){
        AssertUtil.isTrue(null == ids || ids.length == 0,"请选择待删除的用户记录!");
        AssertUtil.isTrue(deleteBatch(ids) != ids.length,"用户记录删除失败!");

        //遍历用户ID的数组
        for (Integer userId:ids){
            //通过用户ID查询对应的用户角色记录
            Integer count = userRoleMapper.countUserRoleByUserId(userId);
            //判断用户角色记录是否存在
            if (count>0){
                //通过用户ID删除对应的用户角色记录
                AssertUtil.isTrue(userRoleMapper.deleteUserRoleByUserId(userId) != count,"删除用户记录失败!");
            }
        }
    }

    /**
     * 用户角色关联
     * @param userId
     * @param roleIds
     */
    public void relationUserRole(int userId,String roleIds){

        //查询用户分配的角色数量
        int count = userRoleMapper.countUserRoleByUserId(userId);
        if (count > 0){
            AssertUtil.isTrue(userRoleMapper.deleteUserRoleByUserId(userId) != count,"用户角色分配失败!");
        }
        if (StringUtils.isNotBlank(roleIds)){
            //重新添加新的角色
            List<UserRole> userRoles = new ArrayList<>();
            for (String s:roleIds.split(",")){
                UserRole userRole = new UserRole();
                userRole.setUserId(userId);
                userRole.setRoleId(Integer.parseInt(s));
                userRole.setCreateDate(new Date());
                userRole.setUpdateDate(new Date());
                userRoles.add(userRole);
            }
            AssertUtil.isTrue(userRoleMapper.insertBatch(userRoles) != userRoles.size(),"用户角色分配失败!");
        }
    }


}
